Že pri prejšnjih nalogah smo spoznali SSČS. Ponovimo še enkrat - seznam seznamov celih števil (SSCŠ) je seznam, katerega elementi so bodisi cela števila bodisi seznami seznamov celih števil. Da bo enostavneje, recimo, da je tudi prazen seznam SSCŠ. Nekaj primerov:
[-1, 2, -3]
[1, [2], 3, [2, 3, 4]]
[[[[0]], 1], [2, [[-3], [4]]]]
Sestavi funkcijo ločiStevila(sscs), ki vrne trojico (poz, nic, neg), ki pove
koliko je v sscs pozitivnih, ničelnih in koliko negativnih celih števil. Za primere od zgoraj so rezultati:
(1, 0, 2)
(6, 0, 0)
(3, 1, 1)
Predpostavi, da je parameter zagotovo SSCS,
def ločiStevila(sscs): '''Razdeli podatke v SSCS na pozitivne, ničelne in negativne''' if len(sscs) == 0 : # tudi prazen seznam je SSCS return (0, 0, 0) # in nima celih števil kolikoPozStevil = 0 kolikoNegStevil = 0 kolikoNic = 0 # pregledamo vse elemente for el in sscs : # če je element 'običajno število' if isinstance(el, int): if el > 0: kolikoPozStevil += 1 elif el < 0: kolikoNegStevil += 1 else: kolikoNic += 1 else : # potem mora pa biti sscs in moramo prešteti vsa cela števila v njem trojka = ločiStevila(el) kolikoPozStevil, kolikoNic, kolikoNegStevil = kolikoPozStevil + trojka[0], \ kolikoNic + trojka[1], kolikoNegStevil + trojka[2] return kolikoPozStevil, kolikoNic, kolikoNegStevil
Sestavi funkcijo jeSSCS(sscs), ki preveri
(vrne True oz. False), če je dan seznam res seznam seznamov celih števil.
POZOR: Python pravi, da je isinstance(True, int) enako True, pa tudi
isinstance(False, int) enako True, zato se "znebi" napačnih logičnih
vrednosti z isinstance(True, bool)
def jeSSCS(sscs): '''Ali je sscs res seznam seznamov celih števil''' if not isinstance(sscs, list): # če sploh ne gre za seznam return False if len(sscs) == 0 : # tudi prazen seznam je SSCS return True # pregledamo vse elemente for el in sscs : # če je element logična vrednost if isinstance(el, bool): return False # če element ni ne SSCS ne celo število if not isinstance(el, int) and \ not jeSSCS(el) : # ne SSCE return False # vsi testi OK return True
Sestavi funkcijo kolikoNapacnih(sscs), ki prešteje,
koliko je v seznamu seznamov celih števil napačnih podatkov, torej elementov, ki
niso ne cela števila, ne SSCŠ. Če argument ni seznam, vrni None
>>>kolikoNapacnih([1, 'bla', 2])
1
>>>kolikoNapacnih([1, [['bla', 'blu'], False], 2])
1
>>>kolikoNapacnih([[1.8], [2, 3, [4]], [False, 4, [True]]])
2
>>>kolikoNapacnih(12)
None
def kolikoNapacnih(sscs): '''Koliko elementov je v sscs napačnih''' if not isinstance(sscs, list): return None kolikoNarobe = 0 # pregledamo vse elemente for el in sscs: if (not isinstance(el, int)) and (not jeSSCS(el)) \ or isinstance(el, bool): kolikoNarobe += 1 return kolikoNarobe
Oznake idej se nanašajo na prosojnice permutacije v spletni učilnici FMF za predmet Programiranje 1 v š.l. 15/16
Če hočemo narediti permutacijo iz 0 elementov, vrnemo tako kot itertools [[]]
Na osnovi ideje 1 smo zgradili osnutek metode permutacijeV1(seznam).
Dopolni ga do delujočega!
def permutacijeV1(seznam):
'''Vrne seznam seznamov, kjer posamezni seznam predstavlja
permutacijo elementov iz seznama '''
... manjka
prviDel = seznam[:-1]
zadnji = seznam[-1]
permPrej = permutacijeV1(prviDel)
# vstavi zadnji na vsa možna mesta
rez = []
for
koncnaPer = permPrej z vstavljenim zadnjim
rez.append(koncnaPer)
...
return sorted(rez)
def permutacijeV1(seznam): '''Vrne seznam seznamov, kjer posamezni seznam predstavlj permutacijo elementov iz seznama ''' if seznam == []: # ni elementov, le prazna permutacija return [[]] if len(seznam) == 1: # en sam element - ena permutacija! return [[seznam[0]]] prviDel = seznam[:-1] zadnji = seznam[-1] permPrej = permutacijeV1(prviDel) rez = [] for posameznaP in permPrej: '''Iz te perm. naredimo len(seznam) novih ''' for i in range(len(seznam)): novaP = posameznaP[:] novaP.insert(i, zadnji) rez.append(novaP) return sorted(rez)
Na osnovi ideje 2 smo zgradili osnutek metode permutacijeV2(seznam).
Dopolni ga do delujočega!
def permutacijeV2(seznam):
'''Vrne seznam seznamov, kjer posamezni seznam predstavlja
permutacijo elementov iz seznama '''
... manjka
vse = []
for ind, elt in enumerate(seznam):
# zgradimo vse permutacije iz ostalih
vsePerm = permutacijeV2(seznam[:ind] + seznam[ind + 1:] )
# in sedaj permutacijam dodamo na začetek element elt
...
...
return sorted(vse)
def permutacijeV2(seznam): '''Vrne seznam seznamov, kjer posamezni seznam predstavlja permutacijo elementov iz seznama ''' if seznam == []: # ni elementov, le prazna permutacija return [[]] vse = [] for ind, elt in enumerate(seznam): # zgradimo vse permutacije iz ostalih vsePerm = permutacijeV2(seznam[:ind] + seznam[ind + 1:] ) # in sedaj permutacijam dodamo na začetek element elt for perm in vsePerm: vse.append([elt] + perm) return sorted(vse)
Na osnovi ideje 3 smo zgradili osnutek metode permutacijeV3(seznam).
Dopolni ga do delujočega!
def permutacijeV3(seznam, doSedaj = []):
'''Vrne seznam vseh možnih permutacij iz elementov v elementi,
ki imajo začetek enak permutaciji, ki so predstava doSedaj'''
# Če smo že na koncu
return [doSedaj]
vse = []
for elt in seznam:
# če elt še lahko dodamo v doslej sestavljeno permutacijo
# generiramo vse permutacije z začetkom doSedaj + [elt]
# dodamo vsem
return sorted(vse)
def permutacijeV3(seznam, doSedaj = []): '''Vrne seznam vseh možnih permutacij iz elementov v elementi, ki imajo začetek enak permutaciji, ki so predstava doSedaj''' if seznam == []: # ni elementov, le prazna permutacija return [[]] if len(seznam) == len(doSedaj):# Če smo že na koncu return [doSedaj] vse = [] for elt in seznam: if not elt in doSedaj: # če elt še lahko dodamo v doslej sestavljeno permutacijo permut = permutacijeV3(seznam, doSedaj + [elt]) # generiramo vse permutacije z začetkom doSedaj + [elt] vse += permut #dodamo vsem return sorted(vse)
Na osnovi ideje 4 smo zgradili osnutek metode permutacijeV4(seznam).
Dopolni ga do delujočega!
import itertools
def permutacijeV4(seznam):
'''Vrne seznam seznamov, kjer posamezni seznam predstavlja
permutacijo elementov iz seznama '''
# uporabimo itertools
# pazimo, ker ta vrne seznam naborov!
return sorted(vse)
import itertools def permutacijeV4(seznam): '''Vrne seznam seznamov, kjer posamezni seznam predstavlja permutacijo elementov iz seznama ''' # uporabimo itertools permu = itertools.permutations(seznam) vse = list(map(list, permu)) # pazimo, ker ta vrne seznam naborov! return sorted(vse)
Sestavi funkcijo izbrisiPrazneMape(potDoMape),
ki v izbrani mapi (in njenih podmapah) pobriše vse prazne datoteke
(tiste z velikostjo 0) in vse prazne mape (tiste, ki ne vsebujejo nobenih datotek ali podmap).
Funkcija naj vrne par, ki ga sestavljata število pobrisanih datotek in število pobrisanih map,
oziroma None, če potDoMape ne opisuje imenika
Pozor: ko zbrišemo prazno datoteko, se lahko sprazni tudi mapa.
Pred testiranjem vedno skopirajte to
datoteko ZIP
(staro mapo PythonOsRek pobrišite!)
in jo razširite (nastala bo mapa PythonOsRek s podmapami testX in EURO2012)
import os def izbrisiPrazneMape(potDoMape): '''Izbriši vse prazne datoteke in prazne mape''' kolikoDat, kolikoMap = 0, 0 if not os.path.isdir(potDoMape): # ni mapa return None vseDat = os.listdir(potDoMape) for datoteka in vseDat: #izbrisemo samo prazne datoteke if os.path.isfile(potDoMape + "\\" + datoteka) and os.path.getsize(potDoMape + "\\" + datoteka) == 0: os.remove(potDoMape + "\\" + datoteka) kolikoDat += 1 elif os.path.isdir(potDoMape + "\\" + datoteka): #filtriramo mape kolDat, kolMap = izbrisiPrazneMape(potDoMape + "\\" + datoteka) kolikoDat += kolDat kolikoMap += kolMap #če je mapa sedaj prazna, jo izbrisemo if len(os.listdir(potDoMape)) == 0: os.rmdir(potDoMape) kolikoMap += 1 return kolikoDat, kolikoMap
Collatzovo zaporedje tvorimo na sledeč način. Začnemo z nekim naravnim
številom
Vse naloge, razen prve, rešite z rekurzijo!
Sestavite funkcijo naslednji_clen(n), ki izračuna člen, ki v Collatzovemu
zaporedju sledi številu n.
def naslednji_clen(n): '''člen, ki v Collatzovemu zaporedju sledi številu `n`''' if n % 2 == 0: return n // 2 else: return 3 * n + 1
Sestavite funkcijo dolzina_zaporedja(n), ki izračuna dolžino Collatzovega
zaporedja, ki se začne s številom n.
def dolzina_zaporedja(n): '''dolžina Collatzovega zaporedja, ki se začne s številom `n`.''' if n == 1: return 1 else: return 1 + dolzina_zaporedja(naslednji_clen(n))
Sestavite funkcijo najvecji_clen(n), ki izračuna največji člen v
Collatzovem zaporedju, ki se začne s številom n.
def najvecji_clen(n): '''največji člen v Collatzovem zaporedju, ki se začne s številom `n`.''' if n == 1: return 1 else: return max(n, najvecji_clen(naslednji_clen(n)))
Sestavite funkcijo najdaljse_zaporedje(m, n), ki vrne dolžino najdaljšega
zaporedja med vsemi tistimi Collatzovimi zaporedji, ki se začnejo s števili
med (vključno) m in n.
def najdaljse_zaporedje(m, n): '''Dolžina najdaljšega zaporedja med vsemi tistimi Collatzovimi zaporedji, ki se začnejo s števili med (vključno) m in n.''' if m == n: return dolzina_zaporedja(m) else: return max(dolzina_zaporedja(m), najdaljse_zaporedje(m + 1, n))